package com.smarteropen.kitchensink.service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.NoResultException;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import javax.validation.Validator;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.smarteropen.kitchensink.dao.MemberRepository;
import com.smarteropen.kitchensink.model.Member;

@Service
public class MemberServiceBean implements MemberService {
	@Autowired
	private MemberRepository memberRepository;

	@Autowired
	private Validator validator;

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void validateAndRegister(Member member) {
		validateMember(member);
		memberRepository.register(member);
	}

	@Override
	public Member findById(Long id) {
		return memberRepository.findById(id);
	}

	@Override
	public Member findByEmail(String email) {
		return memberRepository.findByEmail(email);
	}

	@Override
	public List<Member> findAllOrderedByName() {
		return memberRepository.findAllOrderedByName();
	}

	private void validateMember(Member member) throws ConstraintViolationException, ValidationException {
		Set<ConstraintViolation<Member>> violations = validator.validate(member);

		if (!violations.isEmpty()) {
			throw new ConstraintViolationException(new HashSet<ConstraintViolation<?>>(violations));
		}

		if (emailAlreadyExists(member.getEmail())) {
			throw new ValidationException("Unique Email Violation");
		}
	}

	private boolean emailAlreadyExists(String email) {
		Member member = null;
		try {
			member = memberRepository.findByEmail(email);
		} catch (NoResultException e) {
			// ignore
		}
		return member != null;
	}

}
